<?php
/**
 * @example tokenizer
 * ユニークなトークンを生成する.
 * @code
 * require_once('tokenizer.php');
 * print tokenizer::get() . "\n";
 * print tokenizer::get("") . "\n";
 * print tokenizer::get("_") . "\n";
 * print tokenizer::get("&") . "\n";
 * print tokenizer::get("+") . "\n";
 * @endcode
 * @note まず大抵の状況でユニークになります.
 *
 */

/**
 * tokenizer.
 *
 * @date 2008/07/01
 * @version $Id: tokenizer.php 28 2009-11-26 06:57:56Z tzr250rsp $
 */
class tokenizer{


  /**
   * メインロジック.
   *
   * @param string $delimiter
   * @param bool $flg_ran
   * @param bool $flg_pid
   * @param bool $flg_ip
   * @return string
   */
  static public function _get($delimiter, $flg_ran, $flg_pid, $flg_ip)
  {
    $tokens = array();
    // 秒＆マイクロ秒を取得
    // XXX 関数の復帰値が空白デリミタ.
    list($usec, $sec) = explode(" ", microtime());

    // ここはデフォルト
    // エポック秒：まぁ全部はいらんのでちょっと小さめに
    $tokens[] = $sec - 1079340000;
    //$tokens[] = $sec;
    // マイクロ秒
    $tokens[] = (int)($usec * 1000 * 1000);

    // 乱数.
    if ($flg_ran) {
      $tokens[] = mt_rand();
    }

    // プロセスID
    if ($flg_pid) {
      $tokens[] = getmypid();
    }

    // XXX thread ID ...PHPだと取れない
    //  $tokens[] = threadidを取得する方法( Foo );

    // IPアドレス
    if ($flg_ip) {
      $tokens[] = str_replace(".", "", $_SERVER['REMOTE_ADDR']);
    }

    // で、作成
    $ret = array();
    foreach($tokens as $token) {
      $ret[] = tokenizer::to62($token);
    }
    return implode($delimiter, $ret);
  }


  /**
   * get.
   *
   * @param string $delimiter
   * @return string
   */
  static function get($delimiter = '')
  {
    // とりあえず乱数＋プロセスID
    return tokenizer::_get($delimiter, true, true, true);
  }


  /**
   * 62進に変換.
   *
   * @param  num $dec
   * @return  string
   * @since  1.0
   */
  static private function to62($dec)
  {
    //
    $ar = array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
                "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
                "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
                "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
                "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"
                );

                //
                $ret = "";

                do {
                  $bottom = $dec % 62;
                  $ret = $ar[$bottom] . $ret;
                  $dec = (int)($dec/62);
                } while($dec);

                return $ret;
  }

}
// end of class
?>